/**
 *It is a demo for practicing JAVA. All codes are opened source by Jian.
 */
package jian.tool.daocode.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 实体代码生成
 * 
 * @author Jian
 * @date 2012-7-5
 * @version
 * 
 */
public class CodeEntityHelper {

	/**
	 * 生成实体代码
	 * 
	 * @param packageName
	 * @param className
	 * @param properties
	 * @return
	 */
	public static String generateEntityCode(String packageName,
			String className, final Map<String, String> properties,
			boolean isDBOption) {
		List<String> types = new ArrayList<String>();
		Iterator<Entry<String, String>> it = properties.entrySet().iterator();

		while (it.hasNext()) {
			Entry<String, String> entry = it.next();
			types.add(entry.getKey());
		}

		StringBuffer result = new StringBuffer();

		/* 第一部分为包声明和类型导入部分 @TODO 包声明后续为提供默认值但同时提供可填写的界面(与类名一起) */
		result.append("package " + packageName).append(";\n\n")
				.append(generateImport(types)).append("\n");

		/* Class 开头 @TODO 类名后续为提供默认值但同时提供可填写的界面(与包声明一起) */
		result.append("public class " + className + "Entity"
				+ (isDBOption ? " extends DataObject" : "") + "\n{\n");

		result.append(generatePropertiesPrivate(properties)).append(
				generateMethodGetterAndSetterPublic(properties, isDBOption));

		/* Class 结尾 */
		result.append("}");

		return result.toString();
	}

	/**
	 * 应该只有 Date 需要另外导入, 其他都是默认包 java.lang...
	 * 
	 * @param types
	 * @return
	 */
	private static String generateImport(final List<String> types) {
		for (String importPkg : types) {
			if (importPkg.contains("Date")) // 非完全匹配
			{
				return "import java.util.Date;\n";
			}
		}

		return "";
	}

	/**
	 * 生成私有属性, 属性命名与表字段统一
	 * 
	 * @param properties
	 * @return
	 */
	private static StringBuffer generatePropertiesPrivate(
			final Map<String, String> properties) {
		StringBuffer result = new StringBuffer();
		Iterator<Entry<String, String>> it = properties.entrySet().iterator();

		while (it.hasNext()) {
			Entry<String, String> entry = it.next();
			String columnName = entry.getKey();
			String value = entry.getValue();

			// 字段类型
			String type = value.split("\\.")[0];

			// 加注释
			result.append(addComment(value));

			result.append("\tprivate ");
			result.append(type + " " + columnName + ";\n");
			result.append("\n");
		}

		return result.append("\n");
	}

	/**
	 * 生成公开的 setter 和 getter 方法
	 * 
	 * @param properties
	 * @return
	 */
	private static StringBuffer generateMethodGetterAndSetterPublic(
			final Map<String, String> properties, boolean isDBOption) {

		StringBuffer result = new StringBuffer();
		Iterator<Entry<String, String>> it = properties.entrySet().iterator();
		while (it.hasNext()) {
			Entry<String, String> entry = it.next();
			String var = entry.getKey();
			String value = entry.getValue();

			// 字段类型
			String type = value.split("\\.")[0];

			// 加注释
			// result.append(addComment(value));

			result.append(makeSetter(var, type, isDBOption));
			result.append("\n");

			// // 加注释
			// result.append(addComment(value));

			result.append(makeGetter(var, type));
			result.append("\n");
		}

		return result;
	}

	private static StringBuffer makeSetter(String var, String type,
			boolean isDBOption) {
		StringBuffer result = new StringBuffer("\tpublic ");
		result.append("void" + " set" + var.substring(0, 1).toUpperCase()
				+ var.substring(1) + "(" + type + " " + var + ")\n");
		result.append("\t{\n");
		if (isDBOption) {
			result.append("\t\tif ( this." + var + " != " + var + " )\n");
			result.append("\t\t{\n");
			result.append("\t\t\tthis." + var + " = " + var + ";\n");
			result.append("\t\t\tsetOp(DBOption.UPDATE);\n");
			result.append("\t\t}\n");
		} else {
			result.append("\t\tthis." + var + " = " + var + ";\n");
		}

		result.append("\t}\n");
		return result;
	}

	private static StringBuffer makeGetter(String var, String type) {
		StringBuffer result = new StringBuffer("\tpublic ");
		result.append(type + " get" + var.substring(0, 1).toUpperCase()
				+ var.substring(1) + "()\n");
		result.append("\t{\n");
		result.append("\t\treturn " + var + ";\n");
		result.append("\t}\n");
		return result;
	}

	/**
	 * 添加字段注释
	 * 
	 * @param value
	 * @return
	 */
	private static StringBuffer addComment(String value) {

		StringBuffer result = new StringBuffer("");

		if (value.split("\\.").length > 1) {
			String comment = value.split("\\.")[1];
			result.append("\t").append("/**").append("\n");
			result.append("\t").append(" * ").append(comment).append("\n");
			result.append("\t").append(" */").append("\n");
		}
		return result;
	}
}
